////////////////////////////////////////////////////////////////////////////////
// The following FIT Protocol software provided may be used with FIT protocol
// devices only and remains the copyrighted property of Dynastream Innovations Inc.
// The software is being provided on an "as-is" basis and as an accommodation,
// and therefore all warranties, representations, or guarantees of any kind
// (whether express, implied or statutory) including, without limitation,
// warranties of merchantability, non-infringement, or fitness for a particular
// purpose, are specifically disclaimed.
//
// Copyright 2008 Dynastream Innovations Inc.
////////////////////////////////////////////////////////////////////////////////
// ****WARNING****  This file is auto-generated!  Do NOT edit this file.
// Profile Version = 1.50Release
// Tag = $Name: AKW1_500 $
////////////////////////////////////////////////////////////////////////////////


#include "fit_profile.hpp"

namespace fit
{

static const Profile::SUBFIELD_MAP fileIdProductGarminProductMaps[] =
{
   { 1, 1 }, // manufacturer == garmin
   { 15, 1 }, // manufacturer == dynastream
   { 13, 1 }, // manufacturer == dynastream_oem
};

static const Profile::SUBFIELD fileIdProductSubFields[] =
{
   { fileIdProductGarminProductMaps, "garmin_product", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 3, 132 },
};

static const Profile::FIELD fileIdFields[] =
{
   { 0, 0, "type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "manufacturer", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, fileIdProductSubFields, "product", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 2, 132 },
   { 0, 0, "serial_number", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 140 },
   { 0, 0, "time_created", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 134 },
   { 0, 0, "number", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD fileCreatorFields[] =
{
   { 0, 0, "software_version", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 132 },
   { 0, 0, "hardware_version", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD padFields[] =
{
   { 0, 0, "pad", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD softwareFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "version", "", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 3, 132 },
   { 0, 0, "part_number", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 7 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD capabilitiesFields[] =
{
   { 0, 0, "languages", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 10 },
   { 0, 0, "sports", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 10 },
   { 0, 0, "workouts_supported", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 21, 140 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD fileCapabilitiesFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "flags", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 10 },
   { 0, 0, "directory", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 7 },
   { 0, 0, "max_count", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 132 },
   { 0, 0, "max_size", "bytes", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 134 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::SUBFIELD_MAP mesgCapabilitiesCountNumPerFileMaps[] =
{
   { 0, 2 }, // count_type == num_per_file
};

static const Profile::SUBFIELD_MAP mesgCapabilitiesCountMaxPerFileMaps[] =
{
   { 1, 2 }, // count_type == max_per_file
};

static const Profile::SUBFIELD_MAP mesgCapabilitiesCountMaxPerFileTypeMaps[] =
{
   { 2, 2 }, // count_type == max_per_file_type
};

static const Profile::SUBFIELD mesgCapabilitiesCountSubFields[] =
{
   { mesgCapabilitiesCountNumPerFileMaps, "num_per_file", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { mesgCapabilitiesCountMaxPerFileMaps, "max_per_file", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { mesgCapabilitiesCountMaxPerFileTypeMaps, "max_per_file_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
};

static const Profile::FIELD mesgCapabilitiesFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "file", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "mesg_num", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, 0, "count_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 0 },
   { 0, mesgCapabilitiesCountSubFields, "count", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 3, 3, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD fieldCapabilitiesFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "file", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "mesg_num", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, 0, "field_num", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 2 },
   { 0, 0, "count", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD deviceSettingsFields[] =
{
   { 0, 0, "utc_offset", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 134 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD userProfileFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "friendly_name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 7 },
   { 0, 0, "gender", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, 0, "age", "years", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 2 },
   { 0, 0, "height", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 3, 2 },
   { 0, 0, "weight", "kg", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 4, 132 },
   { 0, 0, "language", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 0 },
   { 0, 0, "elev_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 0 },
   { 0, 0, "weight_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 0 },
   { 0, 0, "resting_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 8, 2 },
   { 0, 0, "default_max_running_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 9, 2 },
   { 0, 0, "default_max_biking_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 10, 2 },
   { 0, 0, "default_max_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 11, 2 },
   { 0, 0, "hr_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 12, 0 },
   { 0, 0, "speed_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 13, 0 },
   { 0, 0, "dist_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 14, 0 },
   { 0, 0, "power_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 16, 0 },
   { 0, 0, "activity_class", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 17, 0 },
   { 0, 0, "position_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 18, 0 },
   { 0, 0, "temperature_setting", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 21, 0 },
   { 0, 0, "local_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 22, 132 },
   { 0, 0, "global_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 23, 13 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD hrmProfileFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "hrm_ant_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 139 },
   { 0, 0, "log_hrv", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 0 },
   { 0, 0, "hrm_ant_id_trans_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 10 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD sdmProfileFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "sdm_ant_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 139 },
   { 0, 0, "sdm_cal_factor", "%", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 2, 132 },
   { 0, 0, "odometer", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 3, 134 },
   { 0, 0, "speed_source", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 0 },
   { 0, 0, "sdm_ant_id_trans_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 10 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD bikeProfileFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 7 },
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, 0, "sub_sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 0 },
   { 0, 0, "odometer", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 3, 134 },
   { 0, 0, "bike_spd_ant_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 139 },
   { 0, 0, "bike_cad_ant_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 139 },
   { 0, 0, "bike_spdcad_ant_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 139 },
   { 0, 0, "bike_power_ant_id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 139 },
   { 0, 0, "custom_wheelsize", "m", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 8, 132 },
   { 0, 0, "auto_wheelsize", "m", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 9, 132 },
   { 0, 0, "bike_weight", "kg", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 10, 132 },
   { 0, 0, "power_cal_factor", "%", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 11, 132 },
   { 0, 0, "auto_wheel_cal", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 12, 0 },
   { 0, 0, "auto_power_zero", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 13, 0 },
   { 0, 0, "id", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 14, 2 },
   { 0, 0, "spd_enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 15, 0 },
   { 0, 0, "cad_enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 16, 0 },
   { 0, 0, "spdcad_enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 17, 0 },
   { 0, 0, "power_enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 18, 0 },
   { 0, 0, "crank_length", "mm", (FIT_FLOAT32)2, (FIT_FLOAT32)-110, 0, 0, 19, 2 },
   { 0, 0, "enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 20, 0 },
   { 0, 0, "bike_spd_ant_id_trans_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 21, 10 },
   { 0, 0, "bike_cad_ant_id_trans_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 22, 10 },
   { 0, 0, "bike_spdcad_ant_id_trans_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 23, 10 },
   { 0, 0, "bike_power_ant_id_trans_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 24, 10 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD zonesTargetFields[] =
{
   { 0, 0, "max_heart_rate", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 2 },
   { 0, 0, "threshold_heart_rate", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 2 },
   { 0, 0, "functional_threshold_power", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 132 },
   { 0, 0, "hr_calc_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 0 },
   { 0, 0, "pwr_calc_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 0 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD sportFields[] =
{
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "sub_sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, 0, "name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 7 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD hrZoneFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "high_bpm", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 2 },
   { 0, 0, "name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 7 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD powerZoneFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "high_value", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, 0, "name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 7 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD metZoneFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "high_bpm", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 2 },
   { 0, 0, "calories", "kcal / min", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 2, 132 },
   { 0, 0, "fat_calories", "kcal / min", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 3, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD goalFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "sub_sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, 0, "start_date", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 134 },
   { 0, 0, "end_date", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 134 },
   { 0, 0, "type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 0 },
   { 0, 0, "value", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 134 },
   { 0, 0, "repeat", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 0 },
   { 0, 0, "target_value", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 134 },
   { 0, 0, "recurrence", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 8, 0 },
   { 0, 0, "recurrence_value", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 9, 132 },
   { 0, 0, "enabled", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 10, 0 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD activityFields[] =
{
   { 0, 0, "timestamp", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "total_timer_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 0, 134 },
   { 0, 0, "num_sessions", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, 0, "type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 0 },
   { 0, 0, "event", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 0 },
   { 0, 0, "event_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 0 },
   { 0, 0, "local_timestamp", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 134 },
   { 0, 0, "event_group", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::SUBFIELD_MAP sessionTotalCyclesTotalStridesMaps[] =
{
   { 1, 5 }, // sport == running
};

static const Profile::SUBFIELD_MAP sessionAvgCadenceAvgRunningCadenceMaps[] =
{
   { 1, 5 }, // sport == running
};

static const Profile::SUBFIELD_MAP sessionMaxCadenceMaxRunningCadenceMaps[] =
{
   { 1, 5 }, // sport == running
};

static const Profile::SUBFIELD sessionTotalCyclesSubFields[] =
{
   { sessionTotalCyclesTotalStridesMaps, "total_strides", "strides", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
};

static const Profile::SUBFIELD sessionAvgCadenceSubFields[] =
{
   { sessionAvgCadenceAvgRunningCadenceMaps, "avg_running_cadence", "strides/min", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 2 },
};

static const Profile::SUBFIELD sessionMaxCadenceSubFields[] =
{
   { sessionMaxCadenceMaxRunningCadenceMaps, "max_running_cadence", "strides/min", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 2 },
};

static const Profile::FIELD sessionFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "event", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "event_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, 0, "start_time", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 134 },
   { 0, 0, "start_position_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 133 },
   { 0, 0, "start_position_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 133 },
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 0 },
   { 0, 0, "sub_sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 0 },
   { 0, 0, "total_elapsed_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 7, 134 },
   { 0, 0, "total_timer_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 8, 134 },
   { 0, 0, "total_distance", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 9, 134 },
   { 0, sessionTotalCyclesSubFields, "total_cycles", "cycles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 10, 134 },
   { 0, 0, "total_calories", "kcal", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 11, 132 },
   { 0, 0, "total_fat_calories", "kcal", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 13, 132 },
   { 0, 0, "avg_speed", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 14, 132 },
   { 0, 0, "max_speed", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 15, 132 },
   { 0, 0, "avg_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 16, 2 },
   { 0, 0, "max_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 17, 2 },
   { 0, sessionAvgCadenceSubFields, "avg_cadence", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 18, 2 },
   { 0, sessionMaxCadenceSubFields, "max_cadence", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 19, 2 },
   { 0, 0, "avg_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 20, 132 },
   { 0, 0, "max_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 21, 132 },
   { 0, 0, "total_ascent", "m", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 22, 132 },
   { 0, 0, "total_descent", "m", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 23, 132 },
   { 0, 0, "total_training_effect", "", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 24, 2 },
   { 0, 0, "first_lap_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 25, 132 },
   { 0, 0, "num_laps", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 26, 132 },
   { 0, 0, "event_group", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 27, 2 },
   { 0, 0, "trigger", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 28, 0 },
   { 0, 0, "nec_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 29, 133 },
   { 0, 0, "nec_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 30, 133 },
   { 0, 0, "swc_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 31, 133 },
   { 0, 0, "swc_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 32, 133 },
   { 0, 0, "normalized_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 34, 132 },
   { 0, 0, "training_stress_score", "tss", (FIT_FLOAT32)10, (FIT_FLOAT32)0, 0, 0, 35, 132 },
   { 0, 0, "intensity_factor", "if", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 36, 132 },
   { 0, 0, "left_right_balance", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 37, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::SUBFIELD_MAP lapTotalCyclesTotalStridesMaps[] =
{
   { 1, 25 }, // sport == running
};

static const Profile::SUBFIELD_MAP lapAvgCadenceAvgRunningCadenceMaps[] =
{
   { 1, 25 }, // sport == running
};

static const Profile::SUBFIELD_MAP lapMaxCadenceMaxRunningCadenceMaps[] =
{
   { 1, 25 }, // sport == running
};

static const Profile::SUBFIELD lapTotalCyclesSubFields[] =
{
   { lapTotalCyclesTotalStridesMaps, "total_strides", "strides", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
};

static const Profile::SUBFIELD lapAvgCadenceSubFields[] =
{
   { lapAvgCadenceAvgRunningCadenceMaps, "avg_running_cadence", "strides/min", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 2 },
};

static const Profile::SUBFIELD lapMaxCadenceSubFields[] =
{
   { lapMaxCadenceMaxRunningCadenceMaps, "max_running_cadence", "strides/min", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 2 },
};

static const Profile::FIELD lapFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "event", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "event_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, 0, "start_time", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 134 },
   { 0, 0, "start_position_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 133 },
   { 0, 0, "start_position_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 133 },
   { 0, 0, "end_position_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 133 },
   { 0, 0, "end_position_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 133 },
   { 0, 0, "total_elapsed_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 7, 134 },
   { 0, 0, "total_timer_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 8, 134 },
   { 0, 0, "total_distance", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 9, 134 },
   { 0, lapTotalCyclesSubFields, "total_cycles", "cycles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 10, 134 },
   { 0, 0, "total_calories", "kcal", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 11, 132 },
   { 0, 0, "total_fat_calories", "kcal", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 12, 132 },
   { 0, 0, "avg_speed", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 13, 132 },
   { 0, 0, "max_speed", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 14, 132 },
   { 0, 0, "avg_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 15, 2 },
   { 0, 0, "max_heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 16, 2 },
   { 0, lapAvgCadenceSubFields, "avg_cadence", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 17, 2 },
   { 0, lapMaxCadenceSubFields, "max_cadence", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 1, 18, 2 },
   { 0, 0, "avg_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 19, 132 },
   { 0, 0, "max_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 20, 132 },
   { 0, 0, "total_ascent", "m", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 21, 132 },
   { 0, 0, "total_descent", "m", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 22, 132 },
   { 0, 0, "intensity", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 23, 0 },
   { 0, 0, "lap_trigger", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 24, 0 },
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 25, 0 },
   { 0, 0, "event_group", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 26, 2 },
   { 0, 0, "normalized_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 33, 132 },
   { 0, 0, "left_right_balance", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 34, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD_COMPONENT recordCompressedSpeedDistanceComponents[] =
{
   { (FIT_FLOAT32)100, (FIT_FLOAT32)0, 6, 12, FIT_FALSE }, // speed
   { (FIT_FLOAT32)16, (FIT_FLOAT32)0, 5, 12, FIT_TRUE }, // distance
};

static const Profile::FIELD_COMPONENT recordCyclesComponents[] =
{
   { (FIT_FLOAT32)1, (FIT_FLOAT32)0, 19, 8, FIT_TRUE }, // total_cycles
};

static const Profile::FIELD_COMPONENT recordCompressedAccumulatedPowerComponents[] =
{
   { (FIT_FLOAT32)1, (FIT_FLOAT32)0, 29, 16, FIT_TRUE }, // accumulated_power
};

static const Profile::FIELD recordFields[] =
{
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "position_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 133 },
   { 0, 0, "position_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 133 },
   { 0, 0, "altitude", "m", (FIT_FLOAT32)5, (FIT_FLOAT32)500, 0, 0, 2, 132 },
   { 0, 0, "heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 2 },
   { 0, 0, "cadence", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 2 },
   { 0, 0, "distance", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 5, 134 },
   { 0, 0, "speed", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 6, 132 },
   { 0, 0, "power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 132 },
   { recordCompressedSpeedDistanceComponents, 0, "compressed_speed_distance", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 2, 0, 8, 13 },
   { 0, 0, "grade", "%", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 9, 131 },
   { 0, 0, "resistance", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 10, 2 },
   { 0, 0, "time_from_course", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 11, 133 },
   { 0, 0, "cycle_length", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 12, 2 },
   { 0, 0, "temperature", "C", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 13, 1 },
   { 0, 0, "speed_1s", "m/s", (FIT_FLOAT32)16, (FIT_FLOAT32)0, 0, 0, 17, 2 },
   { recordCyclesComponents, 0, "cycles", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 0, 18, 2 },
   { 0, 0, "total_cycles", "cycles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 19, 134 },
   { recordCompressedAccumulatedPowerComponents, 0, "compressed_accumulated_power", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 0, 28, 132 },
   { 0, 0, "accumulated_power", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 29, 134 },
   { 0, 0, "left_right_balance", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 30, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD_COMPONENT eventData16Components[] =
{
   { (FIT_FLOAT32)1, (FIT_FLOAT32)0, 3, 16, FIT_FALSE }, // data
};

static const Profile::SUBFIELD_MAP eventDataTimerTriggerMaps[] =
{
   { 0, 0 }, // event == timer
};

static const Profile::SUBFIELD_MAP eventDataCoursePointIndexMaps[] =
{
   { 10, 0 }, // event == course_point
};

static const Profile::SUBFIELD_MAP eventDataBatteryLevelMaps[] =
{
   { 11, 0 }, // event == battery
};

static const Profile::SUBFIELD_MAP eventDataVirtualPartnerSpeedMaps[] =
{
   { 12, 0 }, // event == virtual_partner_pace
};

static const Profile::SUBFIELD_MAP eventDataHrHighAlertMaps[] =
{
   { 13, 0 }, // event == hr_high_alert
};

static const Profile::SUBFIELD_MAP eventDataHrLowAlertMaps[] =
{
   { 14, 0 }, // event == hr_low_alert
};

static const Profile::SUBFIELD_MAP eventDataSpeedHighAlertMaps[] =
{
   { 15, 0 }, // event == speed_high_alert
};

static const Profile::SUBFIELD_MAP eventDataSpeedLowAlertMaps[] =
{
   { 16, 0 }, // event == speed_low_alert
};

static const Profile::SUBFIELD_MAP eventDataCadHighAlertMaps[] =
{
   { 17, 0 }, // event == cad_high_alert
};

static const Profile::SUBFIELD_MAP eventDataCadLowAlertMaps[] =
{
   { 18, 0 }, // event == cad_low_alert
};

static const Profile::SUBFIELD_MAP eventDataPowerHighAlertMaps[] =
{
   { 19, 0 }, // event == power_high_alert
};

static const Profile::SUBFIELD_MAP eventDataPowerLowAlertMaps[] =
{
   { 20, 0 }, // event == power_low_alert
};

static const Profile::SUBFIELD_MAP eventDataTimeDurationAlertMaps[] =
{
   { 23, 0 }, // event == time_duration_alert
};

static const Profile::SUBFIELD_MAP eventDataDistanceDurationAlertMaps[] =
{
   { 24, 0 }, // event == distance_duration_alert
};

static const Profile::SUBFIELD_MAP eventDataCalorieDurationAlertMaps[] =
{
   { 25, 0 }, // event == calorie_duration_alert
};

static const Profile::SUBFIELD_MAP eventDataFitnessEquipmentStateMaps[] =
{
   { 27, 0 }, // event == fitness_equipment
};

static const Profile::SUBFIELD eventDataSubFields[] =
{
   { eventDataTimerTriggerMaps, "timer_trigger", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 0 },
   { eventDataCoursePointIndexMaps, "course_point_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { eventDataBatteryLevelMaps, "battery_level", "V", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 132 },
   { eventDataVirtualPartnerSpeedMaps, "virtual_partner_speed", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 132 },
   { eventDataHrHighAlertMaps, "hr_high_alert", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 2 },
   { eventDataHrLowAlertMaps, "hr_low_alert", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 2 },
   { eventDataSpeedHighAlertMaps, "speed_high_alert", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 132 },
   { eventDataSpeedLowAlertMaps, "speed_low_alert", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 132 },
   { eventDataCadHighAlertMaps, "cad_high_alert", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { eventDataCadLowAlertMaps, "cad_low_alert", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { eventDataPowerHighAlertMaps, "power_high_alert", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { eventDataPowerLowAlertMaps, "power_low_alert", "watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 132 },
   { eventDataTimeDurationAlertMaps, "time_duration_alert", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 134 },
   { eventDataDistanceDurationAlertMaps, "distance_duration_alert", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 1, 134 },
   { eventDataCalorieDurationAlertMaps, "calorie_duration_alert", "calories", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { eventDataFitnessEquipmentStateMaps, "fitness_equipment_state", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 0 },
};

static const Profile::FIELD eventFields[] =
{
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "event", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 0 },
   { 0, 0, "event_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { eventData16Components, 0, "data16", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 0, 2, 132 },
   { 0, eventDataSubFields, "data", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 16, 3, 134 },
   { 0, 0, "event_group", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD deviceInfoFields[] =
{
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "device_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 2 },
   { 0, 0, "device_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 2 },
   { 0, 0, "manufacturer", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 132 },
   { 0, 0, "serial_number", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 140 },
   { 0, 0, "product", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 132 },
   { 0, 0, "software_version", "", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 5, 132 },
   { 0, 0, "hardware_version", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 2 },
   { 0, 0, "cum_operating_time", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 134 },
   { 0, 0, "battery_voltage", "V", (FIT_FLOAT32)256, (FIT_FLOAT32)0, 0, 0, 10, 132 },
   { 0, 0, "battery_status", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 11, 2 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD hrvFields[] =
{
   { 0, 0, "time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 0, 0, 0, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD courseFields[] =
{
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 0 },
   { 0, 0, "name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 7 },
   { 0, 0, "capabilities", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 140 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD coursePointFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "timestamp", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 134 },
   { 0, 0, "position_lat", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 133 },
   { 0, 0, "position_long", "semicircles", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 133 },
   { 0, 0, "distance", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 4, 134 },
   { 0, 0, "type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 0 },
   { 0, 0, "name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 7 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD workoutFields[] =
{
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 0 },
   { 0, 0, "capabilities", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 140 },
   { 0, 0, "num_valid_steps", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 132 },
   { 0, 0, "wkt_name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 8, 7 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::SUBFIELD_MAP workoutStepDurationValueDurationTimeMaps[] =
{
   { 0, 1 }, // duration_type == time
};

static const Profile::SUBFIELD_MAP workoutStepDurationValueDurationDistanceMaps[] =
{
   { 1, 1 }, // duration_type == distance
};

static const Profile::SUBFIELD_MAP workoutStepDurationValueDurationHrMaps[] =
{
   { 2, 1 }, // duration_type == hr_less_than
   { 3, 1 }, // duration_type == hr_greater_than
};

static const Profile::SUBFIELD_MAP workoutStepDurationValueDurationCaloriesMaps[] =
{
   { 4, 1 }, // duration_type == calories
};

static const Profile::SUBFIELD_MAP workoutStepDurationValueDurationStepMaps[] =
{
   { 6, 1 }, // duration_type == repeat_until_steps_cmplt
   { 7, 1 }, // duration_type == repeat_until_time
   { 8, 1 }, // duration_type == repeat_until_distance
   { 9, 1 }, // duration_type == repeat_until_calories
   { 10, 1 }, // duration_type == repeat_until_hr_less_than
   { 11, 1 }, // duration_type == repeat_until_hr_greater_than
   { 12, 1 }, // duration_type == repeat_until_power_less_than
   { 13, 1 }, // duration_type == repeat_until_power_greater_than
};

static const Profile::SUBFIELD_MAP workoutStepDurationValueDurationPowerMaps[] =
{
   { 14, 1 }, // duration_type == power_less_than
   { 15, 1 }, // duration_type == power_greater_than
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueTargetHrZoneMaps[] =
{
   { 1, 3 }, // target_type == heart_rate
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueTargetPowerZoneMaps[] =
{
   { 4, 3 }, // target_type == power
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueRepeatStepsMaps[] =
{
   { 6, 1 }, // duration_type == repeat_until_steps_cmplt
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueRepeatTimeMaps[] =
{
   { 7, 1 }, // duration_type == repeat_until_time
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueRepeatDistanceMaps[] =
{
   { 8, 1 }, // duration_type == repeat_until_distance
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueRepeatCaloriesMaps[] =
{
   { 9, 1 }, // duration_type == repeat_until_calories
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueRepeatHrMaps[] =
{
   { 10, 1 }, // duration_type == repeat_until_hr_less_than
   { 11, 1 }, // duration_type == repeat_until_hr_greater_than
};

static const Profile::SUBFIELD_MAP workoutStepTargetValueRepeatPowerMaps[] =
{
   { 12, 1 }, // duration_type == repeat_until_power_less_than
   { 13, 1 }, // duration_type == repeat_until_power_greater_than
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueLowCustomTargetSpeedLowMaps[] =
{
   { 0, 3 }, // target_type == speed
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueLowCustomTargetHeartRateLowMaps[] =
{
   { 1, 3 }, // target_type == heart_rate
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueLowCustomTargetCadenceLowMaps[] =
{
   { 3, 3 }, // target_type == cadence
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueLowCustomTargetPowerLowMaps[] =
{
   { 4, 3 }, // target_type == power
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueHighCustomTargetSpeedHighMaps[] =
{
   { 0, 3 }, // target_type == speed
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueHighCustomTargetHeartRateHighMaps[] =
{
   { 1, 3 }, // target_type == heart_rate
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueHighCustomTargetCadenceHighMaps[] =
{
   { 3, 3 }, // target_type == cadence
};

static const Profile::SUBFIELD_MAP workoutStepCustomTargetValueHighCustomTargetPowerHighMaps[] =
{
   { 4, 3 }, // target_type == power
};

static const Profile::SUBFIELD workoutStepDurationValueSubFields[] =
{
   { workoutStepDurationValueDurationTimeMaps, "duration_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepDurationValueDurationDistanceMaps, "duration_distance", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepDurationValueDurationHrMaps, "duration_hr", "% or bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 2, 134 },
   { workoutStepDurationValueDurationCaloriesMaps, "duration_calories", "calories", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepDurationValueDurationStepMaps, "duration_step", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 8, 134 },
   { workoutStepDurationValueDurationPowerMaps, "duration_power", "% or watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 2, 134 },
};

static const Profile::SUBFIELD workoutStepTargetValueSubFields[] =
{
   { workoutStepTargetValueTargetHrZoneMaps, "target_hr_zone", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepTargetValueTargetPowerZoneMaps, "target_power_zone", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepTargetValueRepeatStepsMaps, "repeat_steps", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepTargetValueRepeatTimeMaps, "repeat_time", "s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepTargetValueRepeatDistanceMaps, "repeat_distance", "m", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepTargetValueRepeatCaloriesMaps, "repeat_calories", "calories", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepTargetValueRepeatHrMaps, "repeat_hr", "% or bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 2, 134 },
   { workoutStepTargetValueRepeatPowerMaps, "repeat_power", "% or watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 2, 134 },
};

static const Profile::SUBFIELD workoutStepCustomTargetValueLowSubFields[] =
{
   { workoutStepCustomTargetValueLowCustomTargetSpeedLowMaps, "custom_target_speed_low", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepCustomTargetValueLowCustomTargetHeartRateLowMaps, "custom_target_heart_rate_low", "% or bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepCustomTargetValueLowCustomTargetCadenceLowMaps, "custom_target_cadence_low", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepCustomTargetValueLowCustomTargetPowerLowMaps, "custom_target_power_low", "% or watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
};

static const Profile::SUBFIELD workoutStepCustomTargetValueHighSubFields[] =
{
   { workoutStepCustomTargetValueHighCustomTargetSpeedHighMaps, "custom_target_speed_high", "m/s", (FIT_FLOAT32)1000, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepCustomTargetValueHighCustomTargetHeartRateHighMaps, "custom_target_heart_rate_high", "% or bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepCustomTargetValueHighCustomTargetCadenceHighMaps, "custom_target_cadence_high", "rpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
   { workoutStepCustomTargetValueHighCustomTargetPowerHighMaps, "custom_target_power_high", "% or watts", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 1, 134 },
};

static const Profile::FIELD workoutStepFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "wkt_step_name", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 7 },
   { 0, 0, "duration_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 0 },
   { 0, workoutStepDurationValueSubFields, "duration_value", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 6, 2, 134 },
   { 0, 0, "target_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 0 },
   { 0, workoutStepTargetValueSubFields, "target_value", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 8, 4, 134 },
   { 0, workoutStepCustomTargetValueLowSubFields, "custom_target_value_low", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 4, 5, 134 },
   { 0, workoutStepCustomTargetValueHighSubFields, "custom_target_value_high", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 4, 6, 134 },
   { 0, 0, "intensity", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 0 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD totalsFields[] =
{
   { 0, 0, "message_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 254, 132 },
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "timer_time", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 134 },
   { 0, 0, "distance", "m", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 134 },
   { 0, 0, "calories", "kcal", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 134 },
   { 0, 0, "sport", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 0 },
   { 0, 0, "elapsed_time", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 134 },
   { 0, 0, "sessions", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD weightScaleFields[] =
{
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "weight", "kg", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 0, 132 },
   { 0, 0, "percent_fat", "%", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, 0, "percent_hydration", "%", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 2, 132 },
   { 0, 0, "visceral_fat_mass", "kg", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 3, 132 },
   { 0, 0, "bone_mass", "kg", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 4, 132 },
   { 0, 0, "muscle_mass", "kg", (FIT_FLOAT32)100, (FIT_FLOAT32)0, 0, 0, 5, 132 },
   { 0, 0, "basal_met", "kcal/day", (FIT_FLOAT32)4, (FIT_FLOAT32)0, 0, 0, 7, 132 },
   { 0, 0, "physique_rating", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 8, 2 },
   { 0, 0, "active_met", "kcal/day", (FIT_FLOAT32)4, (FIT_FLOAT32)0, 0, 0, 9, 132 },
   { 0, 0, "metabolic_age", "years", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 10, 2 },
   { 0, 0, "visceral_fat_rating", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 11, 2 },
   { 0, 0, "user_profile_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 12, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

static const Profile::FIELD bloodPressureFields[] =
{
   { 0, 0, "timestamp", "s", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 253, 134 },
   { 0, 0, "systolic_pressure", "mmHg", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 0, 132 },
   { 0, 0, "diastolic_pressure", "mmHg", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 1, 132 },
   { 0, 0, "mean_arterial_pressure", "mmHg", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 2, 132 },
   { 0, 0, "map_3_sample_mean", "mmHg", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 3, 132 },
   { 0, 0, "map_morning_values", "mmHg", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 4, 132 },
   { 0, 0, "map_evening_values", "mmHg", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 5, 132 },
   { 0, 0, "heart_rate", "bpm", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 6, 2 },
   { 0, 0, "heart_rate_type", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 7, 0 },
   { 0, 0, "status", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 8, 0 },
   { 0, 0, "user_profile_index", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 9, 132 },
   { 0, 0, "checksum", "", (FIT_FLOAT32)1, (FIT_FLOAT32)0, 0, 0, 252, 2 },
};

const Profile::MESG Profile::mesgs[MESGS] =
{
   { fileIdFields, "file_id", FIT_MESG_NUM_FILE_ID, 7 },
   { fileCreatorFields, "file_creator", FIT_MESG_NUM_FILE_CREATOR, 3 },
   { padFields, "pad", FIT_MESG_NUM_PAD, 2 },
   { softwareFields, "software", FIT_MESG_NUM_SOFTWARE, 4 },
   { capabilitiesFields, "capabilities", FIT_MESG_NUM_CAPABILITIES, 4 },
   { fileCapabilitiesFields, "file_capabilities", FIT_MESG_NUM_FILE_CAPABILITIES, 7 },
   { mesgCapabilitiesFields, "mesg_capabilities", FIT_MESG_NUM_MESG_CAPABILITIES, 6 },
   { fieldCapabilitiesFields, "field_capabilities", FIT_MESG_NUM_FIELD_CAPABILITIES, 6 },
   { deviceSettingsFields, "device_settings", FIT_MESG_NUM_DEVICE_SETTINGS, 2 },
   { userProfileFields, "user_profile", FIT_MESG_NUM_USER_PROFILE, 23 },
   { hrmProfileFields, "hrm_profile", FIT_MESG_NUM_HRM_PROFILE, 6 },
   { sdmProfileFields, "sdm_profile", FIT_MESG_NUM_SDM_PROFILE, 8 },
   { bikeProfileFields, "bike_profile", FIT_MESG_NUM_BIKE_PROFILE, 27 },
   { zonesTargetFields, "zones_target", FIT_MESG_NUM_ZONES_TARGET, 6 },
   { sportFields, "sport", FIT_MESG_NUM_SPORT, 4 },
   { hrZoneFields, "hr_zone", FIT_MESG_NUM_HR_ZONE, 4 },
   { powerZoneFields, "power_zone", FIT_MESG_NUM_POWER_ZONE, 4 },
   { metZoneFields, "met_zone", FIT_MESG_NUM_MET_ZONE, 5 },
   { goalFields, "goal", FIT_MESG_NUM_GOAL, 13 },
   { activityFields, "activity", FIT_MESG_NUM_ACTIVITY, 9 },
   { sessionFields, "session", FIT_MESG_NUM_SESSION, 39 },
   { lapFields, "lap", FIT_MESG_NUM_LAP, 32 },
   { recordFields, "record", FIT_MESG_NUM_RECORD, 22 },
   { eventFields, "event", FIT_MESG_NUM_EVENT, 7 },
   { deviceInfoFields, "device_info", FIT_MESG_NUM_DEVICE_INFO, 12 },
   { hrvFields, "hrv", FIT_MESG_NUM_HRV, 2 },
   { courseFields, "course", FIT_MESG_NUM_COURSE, 4 },
   { coursePointFields, "course_point", FIT_MESG_NUM_COURSE_POINT, 8 },
   { workoutFields, "workout", FIT_MESG_NUM_WORKOUT, 5 },
   { workoutStepFields, "workout_step", FIT_MESG_NUM_WORKOUT_STEP, 10 },
   { totalsFields, "totals", FIT_MESG_NUM_TOTALS, 9 },
   { weightScaleFields, "weight_scale", FIT_MESG_NUM_WEIGHT_SCALE, 14 },
   { bloodPressureFields, "blood_pressure", FIT_MESG_NUM_BLOOD_PRESSURE, 12 },
};

const Profile::MESG* Profile::GetMesg(const FIT_UINT16 num)
{
   for (int i = 0; i < MESGS; i++)
   {
      if (mesgs[i].num == num)
         return &mesgs[i];
   }

   return NULL;
}

const Profile::MESG* Profile::GetMesg(const std::string& name)
{
   for (int i = 0; i < MESGS; i++)
   {
      if (mesgs[i].name == name)
         return &mesgs[i];
   }

   return NULL;
}

const FIT_UINT16 Profile::GetFieldIndex(const FIT_UINT16 mesgNum, const FIT_UINT8 fieldNum)
{
   const MESG *mesg = GetMesg(mesgNum);

   if (mesg == NULL)
      return FIT_UINT16_INVALID;

   for (FIT_UINT16 i = 0; i < mesg->numFields; i++)
   {
      if (mesg->fields[i].num == fieldNum)
         return i;
   }

   return FIT_UINT16_INVALID;
}

const FIT_UINT16 Profile::GetFieldIndex(const std::string& mesgName, const std::string& fieldName)
{
   const MESG *mesg = GetMesg(mesgName);

   if (mesg == NULL)
      return FIT_UINT16_INVALID;

   for (FIT_UINT16 i = 0; i < mesg->numFields; i++)
   {
      if (mesg->fields[i].name == fieldName)
         return i;

      for (FIT_UINT16 j = 0; j < mesg->fields[i].numSubFields; j++)
      {
         if (mesg->fields[i].subFields[j].name == fieldName)
            return i;
      }
   }

   return FIT_UINT16_INVALID;
}

const Profile::FIELD* Profile::GetField(const FIT_UINT16 mesgNum, const FIT_UINT8 fieldNum)
{
   const MESG *mesg = GetMesg(mesgNum);

   if (mesg == NULL)
      return NULL;

   FIT_UINT16 fieldIndex = GetFieldIndex(mesgNum, fieldNum);

   if (fieldIndex >= mesg->numFields)
      return NULL;

   return &(mesg->fields[fieldIndex]);
}

const Profile::FIELD* Profile::GetField(const std::string& mesgName, const std::string& fieldName)
{
   const MESG *mesg = GetMesg(mesgName);

   if (mesg == NULL)
      return NULL;

   FIT_UINT16 fieldIndex = GetFieldIndex(mesgName, fieldName);

   if (fieldIndex >= mesg->numFields)
      return NULL;

   return &(mesg->fields[fieldIndex]);
}

const FIT_UINT16 Profile::GetSubFieldIndex(const std::string& mesgName, const std::string& fieldName, const std::string& subFieldName)
{
   const FIELD *field = GetField(mesgName, fieldName);

   if (field == NULL)
      return FIT_SUBFIELD_INDEX_MAIN_FIELD;

   for (FIT_UINT16 i = 0; i < field->numSubFields; i++)
   {
      if (field->subFields[i].name == subFieldName)
         return i;
   }

   return FIT_SUBFIELD_INDEX_MAIN_FIELD;
}

const Profile::SUBFIELD* Profile::GetSubField(const FIT_UINT16 mesgNum, const FIT_UINT8 fieldNum, const FIT_UINT16 subFieldIndex)
{
   const MESG *mesg = GetMesg(mesgNum);

   if (mesg == NULL)
      return NULL;

   FIT_UINT16 fieldIndex = GetFieldIndex(mesgNum, fieldNum);

   if (fieldIndex >= mesg->numFields)
      return NULL;

   if (subFieldIndex >= mesg->fields[fieldIndex].numSubFields)
      return NULL;
   
   return &(mesg->fields[fieldIndex].subFields[subFieldIndex]);
}

const Profile::SUBFIELD* Profile::GetSubField(const std::string& mesgName, const std::string& fieldName, const std::string& subFieldName)
{
   const MESG *mesg = GetMesg(mesgName);

   if (mesg == NULL)
      return NULL;

   FIT_UINT16 fieldIndex = GetFieldIndex(mesgName, fieldName);

   if (fieldIndex >= mesg->numFields)
      return NULL;

   FIT_UINT16 subFieldIndex = GetSubFieldIndex(mesgName, fieldName, subFieldName);

   if (subFieldIndex >= mesg->fields[fieldIndex].numSubFields)
      return NULL;

   return &(mesg->fields[fieldIndex].subFields[subFieldIndex]);
}

} // namespace fit

